package com.woniu.service;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.bean.*;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Function;
import java.util.stream.Collectors;


// QQUserMapper 虽然不写，但是要注册， extends BaseMapper
// MP 起步的接口 直接裸奔去用BaseMapper
@Service("qqUserService")
public class IQQUserService extends ServiceImpl<BaseMapper<QQUserBean>, QQUserBean> implements IService<QQUserBean> {

    // 建议：这个线程池的初始化操作，放在容器启动的时候就给他加载了
    public static ExecutorService service;

    @Resource(name = "relationServive")
    private IRelationService relationService;

    @Resource(name = "baseInfoService")
    private IBaseInfoService baseInfoService;

    public QQUserBean login(String qqid, String pwd) throws Exception {
        LambdaQueryWrapper<QQUserBean> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(QQUserBean::getQqid,qqid);
        QQUserBean bean = this.getOne(queryWrapper);
        Optional.of(bean).ifPresent(e-> {
            if (!e.getPassWord().equals(pwd)) throw new RuntimeException("用户名或密码不正确！");
            // 高级程序员，要优化一下。 思考一个问题，上面在登录成功这个是主业务流程。
            // 3、用户如果确实成功登录了，那么最后一次登录时间该如何有效、高效，且**不阻塞**当前主业务流程（登录）的进行
            // 登录成功，要更新用户的最后登录时间
            // 解决方案开一个线程来异步处理... 具体代码怎么落实 .
            // 1、new Thread不好
            // 2、通过线程池
            // 3、AOP切面的Asjpect【下线了解补充】
            // 很消耗性能的。线程池有一个就够了
            service.submit(()->{
                bean.setLastLogTime(new Date());
                // 更新操作......
                this.updateById(bean);
                System.out.println("更新时间成功.....");
            });

        });
        return bean;
    }

    public List<QQUserBO> findMyQQFriendList(Long qqid) {

        List<QQUserBO> qqUserBOList = new ArrayList<>();
        // **********************************************对象之间的组装*********************************************8
        List<RelationBean> list = relationService.list(new LambdaQueryWrapper<RelationBean>().eq(RelationBean::getQqid, qqid));
        List<Long> ids = list.stream().map((e) -> e.getRelationQqid()).collect(Collectors.toList());
        List<QQUserBean> qqUserBeans = this.listByIds(ids);
        List<BaseInfoBean> baseInfoBeans = baseInfoService.listByIds(ids);
        // -----------填充qqUserBOList...难点--------------
        qqUserBeans.forEach((e)->{
            QQUserBO bo = new QQUserBO();
            bo.setUserBean(e);
            bo.setRelationBean(list.stream().filter(r-> e.getQqid().longValue() == r.getRelationQqid()).collect(Collectors.toList()).get(0));
            bo.setBaseInfoBean(baseInfoBeans.stream().filter(b->e.getQqid().longValue() == b.getQqid()).collect(Collectors.toList()).get(0));
            qqUserBOList.add(bo);
        });
        return qqUserBOList;
    }

    public IPage<QQUserBO> findMyQQFriendListPage(Long qqid , int pageIndex , int pageSize) {
        List<QQUserBO> qqUserBOList = new ArrayList<>(); // 分页里面要装的数据......
        List<RelationBean> list = relationService.list(new LambdaQueryWrapper<RelationBean>().eq(RelationBean::getQqid, qqid));// 49
        if (CollectionUtils.isEmpty(list)) return null;
        List<Long> ids = list.stream().map((e) -> e.getRelationQqid()).collect(Collectors.toList()); // 取到所有好友的id号码，49
        HashSet<Long> sids = new HashSet<>(ids); // id去重 ， 把list集合转换为HastSet集合。保证数据的唯一性
        Page<QQUserBean> qqUserBeanPage = this.page(new Page<>(pageIndex, pageSize), new LambdaQueryWrapper<QQUserBean>().in(QQUserBean::getQqid,sids));
        Page<BaseInfoBean> baseInfoBeanPage = baseInfoService.page(new Page<>(pageIndex, pageSize), new LambdaQueryWrapper<BaseInfoBean>().in(BaseInfoBean::getQqid, sids));
        if (qqUserBeanPage.getTotal() != baseInfoBeanPage.getTotal()) throw new RuntimeException("数据不一致");
        qqUserBeanPage.getRecords().forEach( e-> {
            QQUserBO bo = new QQUserBO();
            bo.setUserBean(e);
            bo.setRelationBean(list.stream().filter(r-> e.getQqid().longValue() == r.getRelationQqid().longValue()).collect(Collectors.toList()).get(0));
            bo.setBaseInfoBean(baseInfoBeanPage.getRecords().stream().filter(b->e.getQqid().longValue() == b.getQqid().longValue()).collect(Collectors.toList()).get(0));
            qqUserBOList.add(bo);
        });
        IPage<QQUserBO> page = new Page<>(pageIndex,pageSize,qqUserBeanPage.getTotal());

        page.setPages(qqUserBeanPage.getPages()); // 手动设置总页码
        page.setRecords(qqUserBOList); // 手动设置数据
        return page;
    }
}
